/*
 * GoogleAccountManager.java
 * 
 * Copyright©2012-2013 JMAS corporation. All rights reserved.
 */
package jp.co.jmas.jmasvideo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.widget.ArrayAdapter;

/**
 * @author toshio
 * 
 */
public class GoogleAccountManager {
	private static final String AUTH_TOKEN_TYPE_APPENGINE = "ah";

	private static final String AUTH_TOKEN_TYPE_STORAGE = "oauth2:https://www.googleapis.com/auth/devstorage.read_write";

	public static void authorize(final Activity activity, final Callback callback) {
		final AccountManager accountManager = AccountManager.get(activity);

		// 現在使用ユーザアカウントの取得
		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(activity);
		String currentUser = pref.getString(SettingActivity.KEY_ACCOUNT, "");

		List<String> nameList = new ArrayList<String>();
		final Account[] accounts = accountManager.getAccountsByType("com.google");
		for (Account account : accounts) {
			if (account.name.equals(currentUser)) {
				callAuth(accountManager, activity, account, callback);
				return;
			}
			nameList.add(account.name);
		}

		// アカウント選択画面表示
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity, android.R.layout.simple_spinner_dropdown_item, nameList);
		AlertDialog.Builder builder = new AlertDialog.Builder(activity);
		builder.setTitle("Select a Google account");
		builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				callAuth(accountManager, activity, accounts[which], callback);
			}
		});
		builder.show();
	}

	private static void callAuth(final AccountManager accountManager, final Activity activity, final Account account, final Callback callback) {
		final String[] tokens = new String[2];

		// AppEngineのアクセストークン
		accountManager.getAuthToken(account, AUTH_TOKEN_TYPE_APPENGINE, null, activity, new AccountManagerCallback<Bundle> () {
			@Override
			public void run(AccountManagerFuture<Bundle> future) {
				Bundle bundle;
				try {
					bundle = future.getResult();
					tokens[0] = bundle.getString(AccountManager.KEY_AUTHTOKEN);

					// CloudStorageのアクセストークン
					accountManager.getAuthToken(account, AUTH_TOKEN_TYPE_STORAGE, null, activity, new AccountManagerCallback<Bundle> () {
						@Override
						public void run(AccountManagerFuture<Bundle> future) {
							try {
								Bundle bundle = future.getResult();
								tokens[1] = bundle.getString(AccountManager.KEY_AUTHTOKEN);

								// 現在使用ユーザアカウントの取得
								SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(activity);
								Editor editor =pref.edit();
								editor.putString(SettingActivity.KEY_ACCOUNT, account.name);
								editor.commit();

								// コールバック
								callback.success(tokens[0], tokens[1]);

							} catch (OperationCanceledException e) {
								callback.cancel();

							} catch (AuthenticatorException e) {
								callback.failed(e.getMessage());

							} catch (IOException e) {
								callback.failed(e.getMessage());

							}
						}
					}, null);

				} catch (OperationCanceledException e) {
					callback.cancel();

				} catch (AuthenticatorException e) {
					callback.failed(e.getMessage());

				} catch (IOException e) {
					callback.failed(e.getMessage());
				}
			}
		}, null);

	}

	public static interface Callback {
		public void success(String authTokenAppEngine, String authTokenCloudStorage);
		public void cancel();
		public void failed(String message);
	}
}
